# -*- encoding: utf-8 -*-

# import Lib.Logger.log4py as logging
import os
import json
import time
import requests
import random


def create_subgroup_request(catalog_id, feature_id, component_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "featureIds": feature_id,
        "filterType": 0,
        "marketId": 11,
        "languageId": "1",
        "componentId": component_id
    }


def create_component_request(catalog_id, feature_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "featureIds": feature_id,
        "filterType": 0,
        "marketId": 11,
        "languageId": "1"
    }


def create_callout_req(catalog_id, feature_id, component_parent_id, component_id):
    return {
        "catalogueCode": 1,
        "catalogueId": catalog_id,
        "componentId": component_id,
        "parentComponentId": component_parent_id,
        "featureIds": feature_id,
        "filterType": 0,
        "languageId": "1",
        "marketId": 11,
        "vin": "",
        "shoppingListId": -1,
        "sessionData": {
            "anyCatalogueMode": True,
            "currencyCode": "GBP",
            "currencyId": 2,
            "fleetUser": False,
            "languageIsoCode": "en",
            "marketCode": "GB",
            "marketId": 11,
            "showDealershipData": False,
            "showFleet": False,
            "showFluids": False,
            "showLabours": False,
            "showParts": True,
            "showPrices": True,
            "showServices": False,
            "useStaticPrices": True
        }
    }


BRANDS = {
    "Jaguar": '1',
    "LandRover": '2'
}


class JaguarPartFetcher:
    host = 'https://epc.jlr-apps.com'
    # host = "http://106.14.215.75"
    proxy = {
        'http': 'http://106.14.215.75:5870'
        # 'https': 'http://106.14.215.75:5870'
    }
    CATALOG_LIST_URL = host + '/api/vehicles/11?vehicleTypeId={0}&languageId=24&includeFromDate=false&t={1}'
    CATALOG_URL = host + '/api/configurationSummary/catalogueDefault?catalogueId={0}&marketId=11&languageId=24&t={1}'
    SUBGROUP_URL = host + '/api/componentGroup/subGroups?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=24&marketId=11'
    COMPONENT_URL = host + '/api/componentGroup?catalogueCode={0}&catalogueId={1}&featureIds={2}&filterType=0&languageId=24&marketId=11'
    COMPONENT_SECTION_URL = host + '/api/componentSection?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=24&marketId=11'
    CALLOUT_URL = host + '/api/componentSection/callout?catalogueCode={0}&catalogueId={1}&componentId={2}&featureIds={3}&filterType=0&languageId=24&marketId=11&parentComponentId={4}&shoppingListId=-1&vin='

    def __init__(self, brand, root_dir="."):

        #self.logger = logging.get_logger('crawler', 'PartFetcher')

        self.root_dir = root_dir
        self.brand_path = os.path.join(root_dir, "Jaguar")
        self.brand_id = BRANDS["Jaguar"]
        self.curr_path = self.brand_path

        if not os.path.exists(self.brand_path):
            os.makedirs(self.brand_path, exist_ok=True)

    def request_get(self,url, decode_json=True):
        ret = requests.get(url,timeout=60)

        if ret.status_code != 200:
            # self.logger.error(url)
            # self.logger.error(ret.text)
            print('ERROR URL: ' + url)
            print('ERROE INFO: ' + ret.text)
            return None

        if decode_json:
            try:
                ret_json = ret.json()
                return ret_json
            except:
                return None

        return ret.text

    @staticmethod
    def get_time():
        return str(int(round(time.time() * 1000)))

    @staticmethod
    def get_selected_features(primary_features):
        id_set = []
        for primary_feature in primary_features:
            for feature in primary_feature["features"]:
                if feature['selected']:
                    id_set.append(str(feature["id"]))
        return ','.join(id_set)

    def fetch_parts(self, catalog_id, feature_id, component_parent_id, component_id):
        res = {}
        section_url = JaguarPartFetcher.COMPONENT_SECTION_URL.format(self.brand_id, catalog_id, component_id, feature_id)
        try:
            res["section"] = self.request_get(section_url)
            if res["section"] is None:
                #self.logger.error("Missing component section, skipping")
                print('Missing component section, skipping')
                return

            # print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
            time.sleep(random.randint(0, 3))

            filename = res["section"]["componentPathDTOList"][-1]["code"]
            output_filename = os.path.join(self.curr_path, "{0}.json".format(filename))
            if os.path.exists(output_filename):
                print('File already exist, skipping -> '+ output_filename)
                return

            callout_url = JaguarPartFetcher.CALLOUT_URL.format(self.brand_id, catalog_id, component_id, feature_id, component_parent_id)
            res["parts"] = self.request_get(callout_url)
            if res["parts"] is None:
                # self.logger.error("Missing parts section, skipping")
                print('Missing parts section, skipping')
                return

            with open(output_filename, 'w', encoding='utf-8') as fo:
                json.dump(res, fo, ensure_ascii=True, indent=4)
                print('Saved file -> ' + output_filename)
        except KeyError as err:
            err_filename = os.path.join(self.root_dir, "{0}.txt".format('jaguar_part_fetcher_err.txt'))
            with open(err_filename,'a') as f_err:
                f_err.write('ERR_PART -> '+section_url+'\n')
            print(err)


    def fetch_components(self, catalog_id, feature_id, component_id, level=0):
        subgroup_url = JaguarPartFetcher.SUBGROUP_URL.format(self.brand_id, catalog_id, component_id, feature_id)
        subgroup_src = self.request_get(subgroup_url)
        if subgroup_src is None or "subComponents" not in subgroup_src:
            # self.logger.info("No subcomponents in this subgroup")
            print('No subcomponents in this subgroup')
            return

        subgroups = subgroup_src["subComponents"]
        for subgroup in subgroups:
            filter_id = subgroup["componentTypeId"]
            subgroup_id = subgroup["componentId"]
            if filter_id == 4:
                self.fetch_parts(catalog_id, feature_id, component_id, subgroup_id)
            else:
                # self.logger.info("+++PARENT: {0:d}, SUBGROUP: {1:d}".format(component_id, subgroup_id))
                print("+++PARENT: {0:d}, SUBGROUP: {1:d}".format(component_id, subgroup_id))
                self.fetch_components(catalog_id, feature_id, subgroup_id, level + 1)

    def fetch_all(self, offset, limit):
        catalog_url = JaguarPartFetcher.CATALOG_LIST_URL.format(self.brand_id, self.get_time())
        catalogs = self.request_get(catalog_url)
        if not catalogs:
            return

        catalogs = catalogs[offset: offset + limit]
        for catalog in catalogs:
            catalog_id = catalog.get("componentId")
            catalog_url = JaguarPartFetcher.CATALOG_URL.format(catalog_id, self.get_time())
            catalog_obj = self.request_get(catalog_url)
            feature_id = self.get_selected_features(catalog_obj["primaryFeatureCodes"])

            catalog_code = catalog_obj["catalogueCode"]
            self.curr_path = os.path.join(self.brand_path, catalog_code)
            if not os.path.exists(self.curr_path):
                os.makedirs(self.curr_path, exist_ok=True)

            out_file = os.path.join(self.curr_path, 'main.json')
            with open(out_file, 'w') as fo:
                json.dump(catalog_obj, fo, ensure_ascii=True, indent=4)

            component_url = JaguarPartFetcher.COMPONENT_URL.format(self.brand_id, catalog_id, feature_id)
            component_src = self.request_get(component_url)
            components = component_src["subComponents"] if "subComponents" in component_src else []
            for component_parent in components:
                component_id = component_parent["componentId"]
                self.fetch_components(catalog_id, feature_id, component_id)
        print('ALL DATA FETCH COMPLETE ^.^ ')

if __name__ == '__main__':
    import sys

    offset = 0
    limit = 1000
    if len(sys.argv) > 2:
        offset = int(sys.argv[1])
        limit = int(sys.argv[2])

    fetcher = JaguarPartFetcher(".")
    fetcher.fetch_all(offset, limit)